#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <stdint.h>
#include <sys/time.h>
#include <stdio.h>

#include "ring_buf.h"
#include "clog_log.h"
#include "lite_frame_protocol.h"

ring_buf_t *g_ring_buf = NULL;

/**
 * @brief Get ring buffer debug level.
 *
 * This function gets the debug level of a ring buffer.
 *
 * @return int32_t Debug level.
 */
static int32_t get_ring_buf_debug_level(void)
{
    if(NULL == g_ring_buf) {
        clog_log_error("g_ring_buf is null\n");
        return -RET_ERR;
    }
    return g_ring_buf->debug_level;
}

/**
 * @brief Set ring buffer debug level.
 *
 * This function sets the debug level of a ring buffer.
 *
 * @param level Debug level.
 * @return int32_t Status code.
 */
static int32_t set_ring_buf_debug_level(int32_t level)
{
    if(NULL == g_ring_buf) {
        clog_log_error("g_ring_buf is null\n");
        return -RET_ERR;
    }
    g_ring_buf->debug_level = level;
    return RET_OK;
}

/**
 * @brief Get ring buffer status.
 *
 * This function gets the status of a ring buffer.
 *
 * @param ring_buf_status Pointer to the ring buffer status structure.
 * @return int32_t Status code.
 */
static int32_t get_ring_buf_status(ring_buf_status_t *ring_buf_status)
{
    if(NULL == ring_buf_status || NULL == g_ring_buf) {
        clog_log_error("get ring buf status err, buf is null\n");
        return -RET_ERR;
    }

    pthread_mutex_lock(&g_ring_buf->lock);
    ring_buf_status->head = g_ring_buf->head;
    ring_buf_status->tail = g_ring_buf->tail;
    ring_buf_status->size = g_ring_buf->size;
    ring_buf_status->capacity = g_ring_buf->capacity;
    pthread_mutex_unlock(&g_ring_buf->lock);

    return RET_OK;
}

/**
 * @brief Get ring buffer used size.
 *
 * This function gets the used size of a ring buffer.
 *
 * @return int32_t Used size.
 */
static int32_t get_ring_buf_used_size(void)
{
    if(NULL == g_ring_buf) {
        clog_log_error("g_ring_buf is null\n");
        return -RET_ERR;
    }
    return g_ring_buf->size;
}

/**
 * @brief Calculate data transfer rate.
 *
 * This function calculates the data rate in KB/s, given a start time,
 * an end time, and the length of the transferred data in bytes.
 *
 * @param st Start time (struct timespec).
 * @param et End time (struct timespec).
 * @param len Data length in bytes.
 * @return double Data rate in KB/s, or -1 if invalid.
 */
static double calculate_data_rate(struct timespec st, struct timespec et, size_t len)
{
    /* calculate elapsed time */
    double elapsed_seconds = (et.tv_sec - st.tv_sec) + 
                             (et.tv_nsec - st.tv_nsec) / 1e9;

    if (elapsed_seconds <= 0) {
        return 0.0;
    }

    /* convert byte to kb */
    return (len / 1024.0) / elapsed_seconds;
}

/**
 * @brief Initialize the ring buffer structure and resources.
 *
 * This function initializes the ring buffer with the specified input size, including size alignment,
 * memory allocation for buffer structures, and initialization of synchronization primitives. 
 * Key steps: validate input size, align size to RING_BUF_FRAGMENT_SIZE, check against maximum allowed size,
 * allocate memory for ring_buf_t structure and internal buffer, initialize write/read swap buffers,
 * and set up mutex/condition variable for thread safety. Error handling is included for invalid size,
 * memory allocation failures, and synchronization primitive initialization errors.
 *
 * @param buf_size Input buffer size in bytes (must be > 0, will be aligned to RING_BUF_FRAGMENT_SIZE).
 * @return int32_t RET_OK (0) on success; negative error code on failure:
 *         - -RET_ERR: Invalid input size (buf_size <= 0)
 *         - -RET_ERR: Aligned size exceeds CLOG_RING_BUF_MAX_SIZE
 *         - -RET_ERR: Memory allocation failed (ring_buf_t, ring_buf->ring_buf, swap buffers)
 *         - -RET_ERR: Mutex or condition variable initialization failed
 */
static int32_t ring_buf_init(const size_t buf_size)
{
    int32_t ret = RET_OK;
    size_t remainder = 0;
    size_t align_buf_size = 0;
    ring_buf_swap_t *write_swap = NULL;
    ring_buf_swap_t *read_swap = NULL;

    if (buf_size <= 0) {
        clog_log_error("buf_size invalid error, buf_size: %d\n", buf_size);
        return -RET_ERR;
    }

    /* align buf size to RING_BUF_FRAGMENT_SIZE */
    if ((buf_size % RING_BUF_FRAGMENT_SIZE) != 0) {
        remainder = buf_size % RING_BUF_FRAGMENT_SIZE;
        align_buf_size = buf_size + (RING_BUF_FRAGMENT_SIZE - remainder);
    } else {
        align_buf_size = buf_size;
    }

    if(align_buf_size > CLOG_RING_BUF_MAX_SIZE) {
        clog_log_error("buf_size is too large, max size is %d\n", CLOG_RING_BUF_MAX_SIZE);
        return -RET_ERR;
    }

    /* init ring buf */
    if(NULL == g_ring_buf) {
        g_ring_buf = (ring_buf_t *)malloc(sizeof(ring_buf_t));
        if(NULL == g_ring_buf) {
            clog_log_error("malloc ring buf failed\n");
            return -RET_ERR;
        }
        g_ring_buf->head = 0;
        g_ring_buf->tail = 0;
        g_ring_buf->size = 0;
        g_ring_buf->capacity = align_buf_size;
        g_ring_buf->debug_level = 0;
    } else {
        clog_log_error("ring buf is already init\n");
        return -RET_ERR;
    }

    g_ring_buf->ring_buf = (uint8_t *)malloc(align_buf_size * sizeof(uint8_t));
    if(NULL == g_ring_buf->ring_buf) {
        clog_log_error("malloc ring buf ring_buf failed\n");
        ret = -RET_ERR;
        goto err;
    }

    /* init ring buf write_swap */
    write_swap = (ring_buf_swap_t *)malloc(sizeof(ring_buf_swap_t));
    if(NULL == write_swap) {
        clog_log_error("malloc ring buf write_swap failed\n");
        ret = -RET_ERR;
        goto err;
    }
    memset(write_swap, 0x00, sizeof(ring_buf_swap_t));
    g_ring_buf->write_swap = write_swap;
    write_swap->tmp_buf = NULL; /* write don't need tmp_buf */
    write_swap->buf = (uint8_t *)malloc(RING_BUF_SWAP_SIZE * sizeof(uint8_t));
    if(NULL == write_swap->buf ) {
        clog_log_error("malloc ring buf write_swap buf failed\n");
        ret = -RET_ERR;
        goto err;
    }

    /* init ring buf read_swap */
    read_swap = (ring_buf_swap_t *)malloc(sizeof(ring_buf_swap_t));
    if(NULL == read_swap) {
        clog_log_error("malloc ring buf read_swap failed\n");
        ret = -RET_ERR;
        goto err;
    }
    memset(read_swap, 0x00, sizeof(ring_buf_swap_t));
    g_ring_buf->read_swap = read_swap;
    read_swap->buf = (uint8_t *)malloc(RING_BUF_SWAP_SIZE * sizeof(uint8_t));
    if(NULL == read_swap->buf ) {
        clog_log_error("malloc read_swap buf failed\n");
        ret = -RET_ERR;
        goto err;
    }

    read_swap->tmp_buf = (uint8_t *)malloc(RING_BUF_SWAP_SIZE * sizeof(uint8_t));
    if(NULL == read_swap->tmp_buf ) {
        clog_log_error("malloc read_swap tmp_buf failed\n");
        ret = -RET_ERR;
        goto err;
    }

    /* init ring buf lock */
    ret = pthread_mutex_init(&g_ring_buf->lock, NULL);
    if(ret != 0) {
        clog_log_error("pthread_mutex_init failed\n");
        ret = -RET_ERR;
        goto err;
    }

    /* init ring buf cond */
    ret = pthread_cond_init(&g_ring_buf->cond, NULL);
    if(ret != 0) {
        clog_log_error("pthread_cond_init failed\n");
        ret = -RET_ERR;
        goto err;
    }

    g_ring_buf->init_status = 1;
    clog_log_info("ring buf init success, size: %ld\n", align_buf_size);

    return ret;

err:
    if(ret != RET_OK) {
        clog_log_error("ring buf init failed\n");
        if (read_swap != NULL) {
            free(read_swap->tmp_buf);
            free(read_swap->buf);
            free(read_swap);
            read_swap = NULL;
        }

        if (write_swap != NULL) {
            free(write_swap->buf);
            free(write_swap);
            write_swap = NULL;
        }

        if (g_ring_buf != NULL) {
            pthread_cond_destroy(&g_ring_buf->cond);
            pthread_mutex_destroy(&g_ring_buf->lock);
            if (g_ring_buf->ring_buf != NULL) {
                free(g_ring_buf->ring_buf);
                g_ring_buf->ring_buf = NULL;
            }
            free(g_ring_buf);
            g_ring_buf = NULL;
        }
        ret = -RET_ERR;
    }
    return ret;
}

/**
 * @brief Deinitialize the ring buffer structure and release resources.
 *
 * This function deinitializes the ring buffer by releasing all allocated memory
 * and destroying associated synchronization primitives. Key steps: check if the
 * ring buffer is initialized, destroy condition variable and mutex, free read
 * and write swap buffers, free internal ring buffer, and set init status to 0.
 * Error handling is included for uninitialized buffer, failed primitive
 * destruction, and memory deallocation errors.
 *
 * @return int32_t RET_OK (0) on success; negative error code on failure:
 *         - -RET_ERR: Ring buffer not initialized
 *         - -RET_ERR: Failed to destroy condition variable or mutex
 *         - -RET_ERR: Failed to free read or write swap buffers
 *         - -RET_ERR: Failed to free internal ring buffer
 */
static int32_t ring_buf_deinit(void)
{
    int32_t ret = RET_OK;
    ring_buf_swap_t *write_swap = g_ring_buf->write_swap;
    ring_buf_swap_t *read_swap = g_ring_buf->read_swap;

    if (read_swap != NULL) {
        free(read_swap->tmp_buf);
        free(read_swap->buf);
        free(read_swap);
        read_swap = NULL;
    }

    if (write_swap != NULL) {
        free(write_swap->buf);
        free(write_swap);
        write_swap = NULL;
    }

    if (g_ring_buf != NULL) {
        pthread_cond_destroy(&g_ring_buf->cond);
        pthread_mutex_destroy(&g_ring_buf->lock);
        if (g_ring_buf->ring_buf != NULL) {
            free(g_ring_buf->ring_buf);
            g_ring_buf->ring_buf = NULL;
        }
        free(g_ring_buf);
        g_ring_buf = NULL;
    }
    clog_log_info("ring buf deinit success\n");

    return ret;
}

/**
 * @brief Read one fragment to user buffer.
 *
 * This function reads one fragment from the ring buffer and copies it to the
 * user buffer. It also updates the size of the data read.
 *
 * @param user_buf Pointer to the user buffer where the data will be copied.
 * @param size Pointer to the variable that will store the size of the data read.
 * @return int32_t RET_OK on success, negative error code on failure.
 */
static int32_t read_one_fragment_to_user_buf(uint8_t *user_buf, size_t *size)
{
    int32_t ret = RET_OK;
    size_t first_part = 0;
    ring_buf_t *ring_buf = g_ring_buf;
    ring_buf_swap_t *read_swap = NULL;
    size_t payload_offset = 0;
    int32_t frag_status;
    int32_t fragment_count = 0;

    if (NULL == user_buf || NULL == ring_buf || NULL == ring_buf->read_swap) {
        clog_log_error("Invalid parameters: user_buf=%p, ring_buf=%p, read_swap=%p\n", 
               user_buf, ring_buf, ring_buf->read_swap);
        return -RET_ERR;
    }
    read_swap = ring_buf->read_swap;
    fragment_count = read_swap->frag_cnt_total;

    while (fragment_count > 0) {
        /* get the frame of the data head */
        first_part = ring_buf->capacity - ring_buf->head;
        if (first_part >= RING_BUF_FRAGMENT_SIZE) {
            memcpy(read_swap->buf, ring_buf->ring_buf + ring_buf->head, RING_BUF_FRAGMENT_SIZE);
        } else {
            memcpy(read_swap->buf, ring_buf->ring_buf + ring_buf->head, first_part);
            memcpy(read_swap->buf + first_part, ring_buf->ring_buf, RING_BUF_FRAGMENT_SIZE - first_part);
        }

        /* data link layer check */
        ret = data_link_layer_check_interface(read_swap->buf, read_swap);
        if(ret == link_sync_unknown_error) {
            clog_log_error("data_link_layer_check_interface failed, ret: %d\n", ret);
            return -RET_ERR;
        }

        /* resolve fragment */
        frag_status = transport_resolve_fragment_interface(read_swap->buf, read_swap);
        if(frag_status == TP_FRAG_FINISH_FLAG) {
            memcpy(
                read_swap->tmp_buf + payload_offset, 
                read_swap->buf + RING_BUF_HEADER_SIZE, 
                read_swap->frag_last_copy
            );
            payload_offset += read_swap->frag_last_copy;
        } else if(frag_status == TP_FRAG_NOT_FINISH_FLAG) {
            memcpy(
                read_swap->tmp_buf + payload_offset, 
                read_swap->buf + RING_BUF_HEADER_SIZE, 
                TP_FRAGMENT_VALID_SIZE
            );
            payload_offset += TP_FRAGMENT_VALID_SIZE;
        } else {
            clog_log_error("transport_resolve_fragment_interface failed, ret: %d\n", frag_status);
            return -RET_ERR;
        }

        fragment_count -= 1;

        // if(fragment_count == 0) {
        //     ret = frame_is_start_or_end(read_swap->buf);
        //     if(ret != (int32_t)end_frame && ret != (int32_t)single_frame) {
        //         clog_log_error("the end frame check failed, ret: %d\n", ret);
        //         return -RET_ERR;
        //     }
        // }

        ring_buf->head = (ring_buf->head + RING_BUF_FRAGMENT_SIZE) % ring_buf->capacity;
        if(ring_buf->size > RING_BUF_FRAGMENT_SIZE) {
            ring_buf->size -= RING_BUF_FRAGMENT_SIZE;
        } else {
            ring_buf->size = 0;
        }
    }

    memcpy(user_buf, read_swap->tmp_buf, payload_offset);
    *size = (int32_t)payload_offset;

    return RET_OK;
}

/**
 * @brief Put data to ring buffer.
 *
 * This function puts data into the ring buffer. It first locks the ring buffer
 * to ensure thread safety, then sets the transport and data link layer, and
 * finally copies the data into the ring buffer.
 *
 * @param user_data Pointer to the user data to be put into the ring buffer.
 * @param size Size of the user data in bytes.
 * @return int32_t RET_OK on success, negative error code on failure.
 */
static int32_t put_data_to_ring_buf(uint8_t *user_data, size_t size)
{
    int32_t ret = RET_OK;
    ring_buf_t *ring_buf = g_ring_buf;
    ring_buf_swap_t *write_swap = NULL;
    int32_t data_length = (int32_t)size;
    struct timespec start_time, end_time;
    int32_t frag_count = 0;
    size_t total_len;

    if(NULL == ring_buf) {
        clog_log_error("g_ring_buf buf is null\n");
        return -RET_ERR;
    }

    write_swap = ring_buf->write_swap;
    if(NULL == write_swap) {
        clog_log_error("write_swap is null\n");
        return -RET_ERR;
    }

    if(NULL == user_data) {
        clog_log_error("user_data is null\n");
        return -RET_ERR;
    }

    ret = pthread_mutex_lock(&ring_buf->lock);
    if (ret != RET_OK) {
        clog_log_error("pthread_mutex_lock failed\n");
        return -RET_ERR;
    }

    /* transport and data link layer set */
    frag_count = transport_and_data_link_layer_set_interface(user_data, data_length, write_swap);
    if(frag_count < 0) {
        clog_log_error("transport_and_data_link_layer_set_interface failed, ret: %d\n", ret);
        ret = -RET_ERR;
        goto err;
    }

    /* layer head + data */
    total_len = frag_count * RING_BUF_FRAGMENT_SIZE;

    /* Perform data copy into the ring buffer (handling wrap-around) */
    size_t first_part = ring_buf->capacity - ring_buf->tail;
    size_t second_part = total_len - first_part;
    if (first_part >= total_len) {
        memcpy(ring_buf->ring_buf + ring_buf->tail, write_swap->buf, total_len);
    } else {
        memcpy(ring_buf->ring_buf + ring_buf->tail, write_swap->buf, first_part);
        memcpy(ring_buf->ring_buf, write_swap->buf + first_part, second_part);
    }

    /*  Update tail and buffer size */
    if(ring_buf->size + total_len >= ring_buf->capacity) {
        clog_log_error("ring buf put overflow, capacity: %zu, size: %zu, tail: %zu, head: %zud\n",
                ring_buf->capacity, ring_buf->size, ring_buf->tail, ring_buf->head);
        size_t overflow = (ring_buf->size + total_len) - ring_buf->capacity;
        ring_buf->head = (ring_buf->head + overflow) % ring_buf->capacity;
        ring_buf->size = ring_buf->capacity;
    }
    ring_buf->tail = (ring_buf->tail + total_len) % ring_buf->capacity;
    ring_buf->size += total_len;

    ret = pthread_cond_signal(&ring_buf->cond);
    if(ret != 0) {
        clog_log_error("pthread_cond_signal failed\n");
        ret = -RET_ERR;
        goto err;
    }

    ret = pthread_mutex_unlock(&ring_buf->lock);
    if(ret < 0) {
        clog_log_error("pthread_mutex_unlock buf->lock failed\n");
        return -RET_ERR;
    }

    return RET_OK;

err:
    pthread_mutex_unlock(&ring_buf->lock);
    return ret;
}

/**
 * @brief Get data from ring buffer.
 *
 * This function gets data from the ring buffer. It first locks the ring buffer
 * to ensure thread safety, then verifies the first frame, and finally copies
 * the data into the user buffer.
 *
 * @param user_buf Pointer to the user buffer where the data will be copied.
 * @param size Pointer to the variable that will store the size of the data read.
 * @return int32_t RET_OK on success, negative error code on failure.
 */
static int32_t get_data_from_ring_buf(uint8_t *user_buf, size_t *size)
{
    int32_t ret = RET_OK;
    ring_buf_t *ring_buf = g_ring_buf;
    ring_buf_swap_t *read_swap = ring_buf->read_swap;
    struct timespec start_time, end_time;
    size_t total_len;
    size_t first_part = 0;

    if(NULL == ring_buf || NULL == ring_buf->read_swap) {
        clog_log_error("g_ring_buf buf is null\n");
        return -RET_ERR;
    }

    if(NULL == user_buf) {
        clog_log_error("data is null or size invalid\n");
        return -RET_ERR;
    }

    ret = pthread_mutex_lock(&ring_buf->lock);
    if (ret != 0) {
        clog_log_error("pthread_mutex_lock failed\n");
        return -RET_ERR;
    }

    /* no data to read, wait */
    while (ring_buf->size < RING_BUF_FRAGMENT_SIZE) {
        ret = pthread_cond_wait(&ring_buf->cond, &ring_buf->lock);
        if (ret != 0) {
            clog_log_error("pthread_cond_wait failed\n");
            pthread_mutex_unlock(&ring_buf->lock);
            return -RET_ERR;
        }
    }

    /* init read_swap flag */
    read_swap->frag_cnt_set = 0;
    read_swap->frag_cnt_total = 0;
    read_swap->frag_last_copy = 0;
    read_swap->frag_index = 0;
    read_swap->frag_finish_flag = 0;

    /* get the first frame to read_swap->buf */
    first_part = ring_buf->capacity - ring_buf->head;
    if (first_part >= RING_BUF_FRAGMENT_SIZE) {
        memcpy(read_swap->buf, ring_buf->ring_buf + ring_buf->head, RING_BUF_FRAGMENT_SIZE);
    } else {
        memcpy(read_swap->buf, ring_buf->ring_buf + ring_buf->head, first_part);
        memcpy(read_swap->buf + first_part, ring_buf->ring_buf, RING_BUF_FRAGMENT_SIZE - first_part);
    }

    /* set frag_cnt_total and frag_last_copy by the first frame */
    ret = transport_resolve_first_frame_interface(read_swap->buf, read_swap);
    if(ret < 0) {
        clog_log_error("transport_resolve_first_frame check error!\n");
        ret = -RET_ERR;
        goto err;
    }

    /* read all fragment to user buf */
    ret = read_one_fragment_to_user_buf(user_buf, size);
    if(ret < 0) {
        clog_log_error("read_one_fragment error!\n");
        ret = -RET_ERR;
        goto err;
    }

    pthread_mutex_unlock(&ring_buf->lock);

    return ret;
err:
    /* read next data */
    ring_buf->head = (ring_buf->head + RING_BUF_FRAGMENT_SIZE) % ring_buf->capacity;
    if(ring_buf->size > RING_BUF_FRAGMENT_SIZE) {
        ring_buf->size -= RING_BUF_FRAGMENT_SIZE;
    } else {
        ring_buf->size = 0;
    }
    
    pthread_mutex_unlock(&ring_buf->lock);

    return ret;
}

/************************ ring buf interface ************************/

/**
 * @brief Get status of ring buffer.
 *
 * This function gets the status of the ring buffer.
 *
 * @param ring_buf_status Pointer to the ring buffer status structure.
 * @return int32_t RET_OK on success, negative error code on failure.
 */
int32_t get_ring_buf_status_interface(ring_buf_status_t *ring_buf_status)
{
    if(g_ring_buf->init_status == 0) {
        clog_log_error("ring buf not init\n");
        return -RET_ERR;
    }
    return get_ring_buf_status(ring_buf_status);
}

/**
 * @brief Get used size of ring buffer.
 *
 * This function gets the used size of the ring buffer.
 *
 * @return int32_t Used size of the ring buffer in bytes.
 */
int32_t get_ring_buf_used_size_interface(void)
{
    if(g_ring_buf->init_status == 0) {
        clog_log_error("ring buf not init\n");
        return -RET_ERR;
    }
    return get_ring_buf_used_size();
}

/**
 * @brief Set debug level of ring buffer.
 *
 * This function sets the debug level of the ring buffer.
 *
 * @param level Debug level to set.
 * @return int32_t RET_OK on success, negative error code on failure.
 */
int32_t set_ring_buf_debug_level_interface(int32_t level)
{
    if(g_ring_buf->init_status == 0) {
        clog_log_error("ring buf not init\n");
        return -RET_ERR;
    }
    return set_ring_buf_debug_level(level);
}

/**
 * @brief Get debug level of ring buffer.
 *
 * This function gets the debug level of the ring buffer.
 *
 * @return int32_t Debug level of the ring buffer.
 */
int32_t get_ring_buf_debug_level_interface(void)
{
    if(g_ring_buf->init_status == 0) {
        clog_log_error("ring buf not init\n");
        return -RET_ERR;
    }
    return get_ring_buf_debug_level();
}

/**
 * @brief Initialize ring buffer.
 *
 * This function initializes the ring buffer with the specified size.
 * It allocates memory for the buffer and initializes the ring buffer interface.
 *
 * @param buf_size Size of the ring buffer in bytes.
 * @return int32_t RET_OK (0) on success; negative error code on failure:
 *         - -RET_ERR: Buffer size is zero
 *         - -RET_ERR: Ring buffer initialization fails
 */
int32_t ring_buf_init_interface(const size_t buf_size)
{
    return ring_buf_init(buf_size);
}

/**
 * @brief Deinitialize ring buffer.
 *
 * This function deinitializes the ring buffer, freeing allocated memory.
 *
 * @return int32_t RET_OK (0) on success; negative error code on failure:
 *         - -RET_ERR: Ring buffer deinitialization fails
 */
int32_t ring_buf_deinit_interface(void)
{
    if(g_ring_buf->init_status == 0) {
        clog_log_error("ring buf not init\n");
        return -RET_ERR;
    }
    return ring_buf_deinit();
}

/**
 * @brief Put data into ring buffer.
 *
 * This function puts data into the ring buffer.
 *
 * @param data Pointer to the data to be put into the ring buffer.
 * @param size Size of the data in bytes.
 * @return int32_t RET_OK (0) on success; negative error code on failure:
 *         - -RET_ERR: Data is null
 *         - -RET_ERR: Size is zero
 *         - -RET_ERR: Ring buffer is full
 */
int32_t put_data_to_ring_buf_interface(uint8_t *data, size_t size)
{
    if(g_ring_buf->init_status == 0) {
        clog_log_error("ring buf not init\n");
        return -RET_ERR;
    }
    return put_data_to_ring_buf(data, size);
}

/**
 * @brief Get data from ring buffer.
 *
 * This function gets data from the ring buffer.
 *
 * @param data Pointer to the buffer to store the retrieved data.
 * @param size Pointer to the variable to store the size of the retrieved data.
 * @return int32_t RET_OK (0) on success; negative error code on failure:
 *         - -RET_ERR: Data is null
 *         - -RET_ERR: Size is null
 *         - -RET_ERR: Ring buffer is empty
 */
int32_t get_data_from_ring_buf_interface(uint8_t *data, size_t *size)
{
    if(g_ring_buf->init_status == 0) {
        clog_log_error("ring buf not init\n");
        return -RET_ERR;
    }
    return get_data_from_ring_buf(data, size);
}